package customerEnter.Frame.conntroller;

import static com.google.common.collect.Maps.newHashMap;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.aspectj.lang.ProceedingJoinPoint;

import com.google.common.collect.Lists;

import customerEnter.Frame.Annotation.FrameDataSourceController;
import customerEnter.Frame.Annotation.FrameEncryptionTime;
import customerEnter.Frame.Annotation.FrameParameterDecrypt;
import customerEnter.Frame.AnnotationExecute.AnnotationExecute;
import customerEnter.Frame.Enum.DataSourceControllerEnum;
import customerEnter.Frame.Enum.T_SQLConditionEnum;
import customerEnter.Frame.JDBCDao.JdbcTemplate.RandomDataSource;
import customerEnter.Frame.JDBCDao.daoFrame.SqlDataBaseController;
import customerEnter.Frame.JDBCDao.util.DaoFrameConntroller;
import customerEnter.Frame.Utils.Log4j;
import customerEnter.tool.WhetherToEmpty;

/**
 * aop的助手類
 * 
 * 类名称：BaseConntrollerFrameHelp 类描述： 创建人：dy 创建时间：2016-8-31 上午11:28:26
 * 
 */
public class BaseConntrollerFrameHelp {
	/**
	 * 輸出日誌信息
	 */
	protected static void outLog4jInfo(ProceedingJoinPoint joinpoint) {
		Log4j.setLog4j(joinpoint.getThis().getClass());
		Log4j.Log4jOutInfo("類名：" + joinpoint.getTarget().getClass().getName());
		Log4j.Log4jOutInfo("方法名：" + joinpoint.getSignature().getName());

	}

	/**
	 * 運行當前進入aop的方法
	 */
	protected static Object runMainMethod(ProceedingJoinPoint joinpoint) throws Throwable {
		return joinpoint.proceed();
	}

	/**
	 * 查看ConntroJsonMap有沒有數據 有就用out put發送
	 * 
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	protected static void CalculationMapSen(ProceedingJoinPoint joinpoint) throws IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {
		int inobj = 0;
		Object[] objects = null;

		Method[] methods = joinpoint.getThis().getClass().getDeclaredMethods();
		Map<String, Method> mapMethod = new HashMap<String, Method>();

		for (Method method : methods) {
			mapMethod.put(method.getName(), method);
		}

		inobj = ifSend(mapMethod, joinpoint, objects, "getConntroJsonObject", "getConntroJsonMap");
		sendOutPrintData(mapMethod.get("sendOutPrint"), joinpoint, inobj);
	}

	public static int ifSend(Map<String, Method> mapMethod, ProceedingJoinPoint joinpoint, Object[] objects,
			String... is) {
		int i = 0;
		for (String string : is) {
			i = IfConntroJsonMapSize(MethodInvoke(mapMethod.get(string), joinpoint, objects));
			if (i == 1) {
				break;
			}
		}
		return i;
	}

	// 判斷要不要發送數據
	public static Object MethodInvoke(Method method, ProceedingJoinPoint joinpoint, Object... objects) {
		Object object = null;
		try {
			object = method.invoke(joinpoint.getThis(), objects);

		} catch (IllegalAccessException e) {

			Log4j.Log4JOutError(e.getMessage());
		} catch (IllegalArgumentException e) {

			Log4j.Log4JOutError(e.getMessage());
		} catch (InvocationTargetException e) {

			Log4j.Log4JOutError(e.getMessage());
		}

		return object;
	}

	/**
	 * 判斷有沒有值
	 */
	public static int IfConntroJsonMapSize(Object object) {
		if (!WhetherToEmpty.ObjectWhetherToEmpty(object)) {
			return 1;
		} else {
			return 0;
		}
	}

	/**
	 * 發送數據到頁面
	 */
	public static void sendOutPrintData(Method method, ProceedingJoinPoint joinpoint, int... is) {
		Object[] objects = null;
		for (int i : is) {
			if (i == 1) {
				MethodInvoke(method, joinpoint, objects);
				Log4j.Log4jOutInfo("啟動 sendOutPrint  發送數據");
				break;
			}
		}
	}

	static Map<String, Long>	timeLong	= newHashMap();
	static Map<String, Method>	methods		= newHashMap();

	public static Method getBaseConntrollerMethod(String methodName) {
		if (methods.containsKey(methodName)) {
			return methods.get(methodName);
		} else {
			Method[] methodEn = BaseConntrollerFrame.class.getDeclaredMethods();
			for (Method method : methodEn) {
				methods.put(method.getName(), method);
			}
		}
		return methods.get(methodName);

	}

	/**
	 * 加密地址的判斷
	 */
	@SuppressWarnings("unused")
	public static boolean _termTime(ProceedingJoinPoint joinpoint) throws NoSuchMethodException, SecurityException {
		Class<?> class1 = joinpoint.getTarget().getClass();
		String methodName = joinpoint.getSignature().getName();
		String key = class1.getName() + "." + methodName;
		Object This = joinpoint.getThis();
		Method method = AnnotationExecute.getThisMethod(class1, methodName);
		FrameEncryptionTime frameEncryptionTime = method.getAnnotation(FrameEncryptionTime.class);
		if (!WhetherToEmpty.ObjectWhetherToEmpty(frameEncryptionTime)) {
			long annotationlo = 0;
			// 獲取到註解的設置時間
			if (timeLong.containsKey(key)) {
				annotationlo = timeLong.get(key);
			} else {
				if (methodName.equals(method.getName())) {
					annotationlo = frameEncryptionTime.time();
					timeLong.put(key, annotationlo);
				}
			}
			// 獲取傳輸過來的時間
			Method _termTime = getBaseConntrollerMethod("_termTime");
			Method asEncryption = getBaseConntrollerMethod("AsEncryption");
			long lo = (long) MethodInvoke(_termTime, joinpoint, null);
			// System.out.println("時間:" + lo);
			boolean bool = (boolean) MethodInvoke(asEncryption, joinpoint, null);
			if (bool == false || lo == 0) {
				Method sendAsEncryptionError = getBaseConntrollerMethod("sendAsEncryptionError");
				// 設置失敗消息
				MethodInvoke(sendAsEncryptionError, joinpoint, null);
				return false;
			}
			if (annotationlo > lo && lo > 0) {
				return true;
			} else {
				Method sendAsEncryptionError = getBaseConntrollerMethod("sendAsTimeError");
				MethodInvoke(sendAsEncryptionError, joinpoint, null);
				return false;
			}
		} else {
			return true;
		}
	}

	public static void readWithController(ProceedingJoinPoint joinpoint) {
		Class<?> class1 = joinpoint.getTarget().getClass();
		String methodName = joinpoint.getSignature().getName();
		String keyName = class1.getName() + "." + methodName;
		FrameDataSourceController frameDataSourceController = null;
		if (!DaoFrameConntroller.getDataSourceRW().containsKey(keyName)) {
			Method method = AnnotationExecute.getThisMethod(class1, methodName);
			frameDataSourceController = method.getAnnotation(FrameDataSourceController.class);
			DaoFrameConntroller.getDataSourceRW().put(keyName, frameDataSourceController);
		} else {
			frameDataSourceController = DaoFrameConntroller.getDataSourceRW().get(keyName);
		}

		if (!WhetherToEmpty.ObjectWhetherToEmpty(frameDataSourceController)) {
			// 如果設置了讀寫分離註解 就以讀寫分離註解為主
			SqlDataBaseController.setDataBase(frameDataSourceController.dataBase());
			RandomDataSource.setDataSourceController(frameDataSourceController.sourceController());
		} else {
			SqlDataBaseController.setDataBase(T_SQLConditionEnum.DataBase);
			// 否則就以默認為主
			RandomDataSource.setDataSourceController(DataSourceControllerEnum.dataSource_read);
		}
	}

	/**
	 * 加密地址的判斷
	 */
	@SuppressWarnings({ "unused", "unchecked" })
	public static void ParameDecrypt(ProceedingJoinPoint joinpoint, final String name) throws NoSuchMethodException,
			SecurityException {
		Class<?> class1 = joinpoint.getTarget().getClass();
		Object on1 = joinpoint.getTarget();
		String methodName = joinpoint.getSignature().getName();
		String ClassName = name;
		String key = class1.getName() + "." + methodName;
		Object This = joinpoint.getThis();
		Method method = AnnotationExecute.getThisMethod(class1, methodName);
		FrameParameterDecrypt frameEncryptionTime = method.getAnnotation(FrameParameterDecrypt.class);
		if (!WhetherToEmpty.ObjectWhetherToEmpty(frameEncryptionTime)) {
			Method pamar = getBaseConntrollerMethod("setPamar");
			String[] strings = frameEncryptionTime.pams();
			List<String> list = Lists.newArrayList();
			for (String string : strings) {
				list.add(string);
			}
			MethodInvoke(pamar, joinpoint, list);
			// Map<String, String[]> map = (Map<String, String[]>)
			// MethodInvoke(pamar, joinpoint, list);
			// Map<String, String[]> map2 = newHashMap();
			// for (String string : list) {
			// map2.put(string, map.get(string));
			// }

			// try {
			// FrameJavassistUtils.writeClassParamet(ClassName, methodName,
			// list, map2);
			// } catch (Exception e) {
			// e.printStackTrace();
			// }
		}
	}
}
